-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #2833: Fixes to harmonize #2843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When checking a pattern `p` against a selector `s` we should check that `p == s` is typable. So far we did this in a roundabout way by calling homogenizeType and canCheckEquals diretcly. But that is correct only if there are no user-defined definitions of `==`.
We now widen a vararg parameter or alternative of an If or Match only to another numeric value type only if the original type is a constant type, and the type can be widened without loss of precision (here we deem it acceptable that Ints are widened to Floats, but Longs can only be widened to Doubles).
After erasure, the rhs of an inline val like inline val n = 3 no longer has a constant type. Therefore, we need to disable the check for it after erasure. Test case (discovered by accident) in harmonize.scala.
Also, adapt the algorithm to the reference (i.e. convert only if the resulting types all agree).
title: Dropped: Weak Conformance | ||
--- | ||
|
||
In some situations, Scala used a {\em weak conformance} relation when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you can use latex code in our documentation. You should be able to write *weak conformance*
instead which should be rendered as weak conformance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. That comes from switching context from writing a paper with LaTex...
|
||
__Examples:__ | ||
|
||
inline val b: Byte = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good if there was some explanation of how the rules differ between val
and inline val
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the fix! A few comments on the docs.
inline val s: Short = 33 | ||
def f(): Int = b + s | ||
List(b, s, 'a') : List[Int] | ||
List(b, s, 'a', f()): List[Int] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to note here that the type is List[Int]
because Int
is the LUB, not because of the new rule.
List(n, c, d) // used to be: List[Double], now: List[AnyVal] | ||
|
||
Here, it is less clear why the type should be widened to | ||
`List[Double]`, a `List[AnyVal` seems to be an equally valid -- and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing bracket: List[AnyVal]
|
||
To simplify the underlying type theory, Dotty drops the notion of weak | ||
conformance altogether. Instead, it provides more flexibility when | ||
assigning a type to a constant expression. The rule is: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this rule have a name? Is it a new Dotty feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it so say that it is new. It does not have a name (yet).
|
||
- If a list of expressions `Es` appears as one of | ||
|
||
- the elements of a vararg parameter, or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when it's not a vararg parameter list?
def add[T](a: T, b: T): List[T] = List(a, b)
add(1.0f, 1L) // Double?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, AnyVal.
List(b, s, 'a') : List[Int] | ||
List(b, s, 'a', f()): List[Int] | ||
List(1.0f, 'a', 0) : List[Float] | ||
List(1.0f, 1L) : List[Double] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a 1: Int
here to highlight the difference between f()
and 1: Int
?
|
||
__Examples:__ | ||
|
||
inline val b: Byte = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if this is final
instead of inline
?
If I get am LGTM today we can still roll this in the release... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
There are cases where the behavior is different from 2.12
scala> List(1L, 1f)
res1: List[Float] = List(1.0, 1.0) // Dotty yields Double
We'll have to see how much this impacts code in the wild.
We try to replace harmonize with something weaker that only applies to constants.
As a first step: make pattern matching typecheck more principled
When checking a pattern
p
against a selectors
we should checkthat
p == s
is typeable. So far we did this in a roundabout wayby calling harmonizeType and canCheckEquals directly. But that
is correct only if there are no user-defined definitions of
==
.The new algorithm for harmonize is described a new section of the language reference.